import { View} from '@tarojs/components';
import s from './index.module.scss'
import {Children, useEffect, useRef, useState } from 'react';
import classNames from 'classnames';
import Icon from 'components/Icon'


interface carouselProps {
  loop?: boolean,
  loop_direction?: string,
  children?: any,
  arrow?: boolean,
  dot?: boolean,
  touch?: boolean,
  height?: number,
  translateZ?: number,
  button_z?: number
}

export default function Carousel(props: carouselProps) { 
  const  {
    dot = false, //是否显示小圆点按钮
    loop = false, //是否自动播放
    loop_direction = 'next', //自动播放的方向，默认 next，还可以设置 prev
    arrow = true, //是否显示箭头按钮
    touch = true, //是否可以拖拽元素
    children, //传入的数据类型，应该为多个，传入过后可以拿到一个数组，遍历渲染
    height = 300, //元素的高，宽度固定 300px
    translateZ = 300, //轮播图到中心点的距离
    button_z = 350 //几个按钮到中心点的距离，防止被图片遮挡，所以要比图片 z 轴更高
  } = props
  const [touchStartX, setTouchStartX] = useState(0)
  const [touchMoveX, setTouchMoveX] = useState(0)
  const [rotate, setRotate] = useState(0)
  const rotate_value = useRef(0)
  const [current, setCurrent] = useState(0)
  const position = useRef(0)
  const timer = useRef<any>(null)

  // 闭包会缓存值，用回调函数解决闭包问题
  const [active, setActive] = useState(true)
  const __box = classNames(s.box, {
    [s.active]: active
  })
  rotate_value.current = 360 / children.length
  if(position.current === -360) { 
    position.current = 0
    setCurrent(0)
    setTimeout(() => {
      setActive(false)
      setRotate(0)
    },200)
  }
  if(rotate_value.current != 0) {
    if (position.current === rotate_value.current) {
      const max = children.length - 1
      position.current = -max * rotate_value.current
      setCurrent(max)
      setTimeout(() => {
        setActive(false)
        setRotate(position.current)
      }, 200)
    }
  }
  
  function touchstart(e) {
    setTouchMoveX(e.touches[0].clientX)
    setTouchStartX(e.touches[0].clientX)
    setActive(false)
    clearInterval(timer.current)
  }
  function touchmove(e) {
    const disX = e.touches[0].clientX - touchMoveX
    setTouchMoveX(e.touches[0].clientX)
    setRotate(rotate + disX * (rotate_value.current / 300))
  }
  function touchend(e) {
    const _end = e.changedTouches[0].clientX
    if(_end - touchStartX >= 100) {
      movePrev()
    } else if(_end - touchStartX <= -100) {
      moveNext()
    } else {
      setRotate(position.current)
    }
    setActive(true)
    setTimer()
  }
  function moveNext() {
    position.current -= rotate_value.current
    setRotate(position.current)
    setCurrent((pre) => {
      let __current = pre + 1
      if (__current > children.length - 1) {
        return 0
      } else {
        return __current
      }
    })
  }
  // prev:上一个  next：下一个 current loop=true direction
  function movePrev() {
    position.current += rotate_value.current
    setRotate(position.current)
    setCurrent((pre) => {
      let __current = pre - 1
      if (__current < 0) {
        return children.length - 1
      } else {
        return __current
      }
    })
  }

  function clickDot(index) {
    setCurrent(index)
    clearInterval(timer.current)
    if(current != index ){
      position.current = -index * rotate_value.current
      setRotate(position.current)
      setActive(true)
      setTimer()
    }  else {
      setActive(true)
      setTimer()
    }
  }

  function setTimer() {
    if (!loop) return
    if(loop_direction == 'next') {
      timer.current = setInterval(() => {
        setActive(true)
        moveNext()
      }, 5000)
    } else if (loop_direction == 'prev') {
      timer.current = setInterval(() => {
        setActive(true)
        movePrev()
      }, 5000)
    }
  }
  useEffect(() =>{
    setTimer()
  },[])



  return (
    <View className={s.camera}>
      <View className={s.space} style={{height:`${height}px`}}>
        <View 
          className={__box}
            onTouchStart={ touch ? touchstart : undefined }
            onTouchMove={ touch ? touchmove : undefined}
            onTouchEnd={ touch ? touchend : undefined}
          id='box'
          style={{transform: `rotateY(${rotate}deg)` }}
        >
          {/* 不能直接用传入的 children数组，因为当只有一个子节点的时候，React 不会构建数组，map 不会遍历空数组，使用Children.map 方法，即使只传入一个子元素也可以渲染出来 */}
          {Children.map(children,(item, index) =>(
            <View
              className={s.side}
              style={{ transform: `rotateY(${index * rotate_value.current}deg)  translateZ(${translateZ}px) `}}
            >{item}</View>
          ))}
        </View>

        {arrow ? (
          <View>
              {/* 左边的按钮往上一页翻 */}
            <View 
              className={s.btn_left} 
              onClick={() => {
                clearInterval(timer.current)
                movePrev()
                setTimer()
                setActive(true)
              }}

              style={{ transform: `translateY(-50%) translateZ(${button_z}px)` }}
            >
              <Icon name='chevron-down' size={50} style={{ transform: 'rotate(90deg)' }} />
            </View>
            {/* 右边的按钮往下一页翻 */}
            <View
             className={s.btn_right} 
             onClick={() => {
              clearInterval(timer.current)
              moveNext()
              setTimer()
              setActive(true)
            }}
              style={{ transform: `translateY(-50%) translateZ(${button_z}px)`}}
            >
              <Icon name='chevron-up' size={50} style={{ transform: 'rotate(90deg)' }} />
            </View>
          </View>
        ) : null }

        {dot ? (
          <View className={s.points}
            style={{ transform: `translateX(-50%) translateZ(${button_z}px)` }}>
            {Children.map(children,(item,index) => (
              <View className={s.dot_container} onClick={() => clickDot(index)}>
                <View className={current == index ? `${s.dot} ${s.select}` : s.dot} ></View>
              </View>
            ))}
          </View>
        ) : null}
      </View>
    </View>
  )
}